package mianshi;

public class SessionText {
    /**
     * 1.分布式session的实现方案（4种）
     * <p>
     * 1.1 粘性session
     * 粘性session就是将用户的请求都锁定在一台机器上，哪台机器获取到了
     * 用户的session, 那么就将该用户的请求都分发到这台机器上
     * 实现方式：通过nginx，实现请求的粘性分发，在upstream模块配置ip_hash属性即可实现粘性session
     * 优点：实现简单，不需要对session进行任何处理
     * 缺点：缺乏容错性，如果用户session绑定的机器宕机了，那么就要重新登陆
     * <p>
     * 1.2 保存到数据库中
     * 将用户的session信息保存到数据库中，当session失效时删除
     * 优点：服务器宕机时，session不会丢失
     * 缺点：消耗数据库性能，如果session信息过多，则会影响到数据库的性能
     * <p>
     * 1.3 保存到缓存中，如redis和Memcached （最常用的方式）
     * 将session保存到缓存中，读取session时从缓存中读取
     * 而redis也分为单机和集群部署，单机不多说，集群时也可以通过主从复制的方式实现session的共享
     * 优点：可容错，应该算是最优解
     * <p>
     * 1.4 服务器的session复制
     * 原理：任何一台服务器的session信息发生改变，都会通过广播的方式分发到其他的机器上
     * 实现方式：设置tomcat开启tomcat集群功能
     * 优点：可容错
     * 缺点：1.同步session时会同步到所有的机器上，但是有些机器此时并不需要该用户的session,因此浪费性能
     * 2.如果session量过大的话，会对网络造成一定的压力，影响服务器性能
     */
    private int minStartValue(int[] nums) {
        if (nums == null || nums.length == 0) {
            return 1;
        }
        int min = Integer.MAX_VALUE;
        int sum = 0;
        for (int i = 0; i < nums.length; i++) {
            sum += nums[i];
            min = Math.min(sum, min);
        }
        return min < 0 ? 1 - min : 1;
    }
    /*
            分布式锁
        1.通过数据库的主键ID冲突来实现分布式锁
            例如某个方法要加上分布式锁,可以在数据库创建一个方法名称的主键字段,获取锁时,insert一条数据,
            只有insert成功的线程才能往下执行,解锁时就是删掉该条记录
        缺点:
        1.依赖数据库,如果数据库挂了,那么整个业务将不可用.
            解决方法:使用多个数据库
        2.锁没有失效时间,假如解锁失败(即删除记录失败),那么其他线程将再也无法获取到锁
            解决方法:可以设置一个定时器,定时删除超时解锁失败的数据
        3.锁是非重入的,因为第一次获取锁的时候,数据记录已经存在了,即使是同一个线程,也无法获取第二次锁
            解决方法:可以在记录中再加一个字段,记录获取锁的线程ID,在获取锁时,先查询数据库中是否存在锁并且
            是否是当前线程,如果是当前线程则直接获取锁(即执行同步业务)
        4.锁是非阻塞的,因为其他线程在获取锁失败的时候(即执行insert语句失败时),会直接报错.要想获取锁,
        必须再次执行一次请求锁的操作
            解决方法:使用一个死循环,不断的获取锁,获取成功时退出

        2.使用redis中的setnx实现分布式锁
            setnx是一个原子性操作,成功时会返回1,失败时会返回0.使用setnx来实现请求锁的操作
            实现方式:
            1.setnx获取锁,获取成功返回1,失败返回0;
            2.expire设置超时时间,防止redis宕机导致死锁
            3.业务执行完成之后,使用delete删除key完成解锁操作
        优点:实现简单,加锁流程和解锁流程都很快
        存在的问题:
            1.setnx成功后,在expire设置过期之前宕机了,会导致死锁的问题
            解决方法:
            2.失效时间设置多少好?如果设置时间过长,会造成不必要的阻塞;如果设置时间太短,那么
            可能会存在方法还没执行完成,但是已经解锁了,也还是会存在并发问题.
            解决方法:在设置过期时间时,只设置很短的时间,但是要新开一个线程,不断的扫描判断业务是否执行完成,未执行完成时,
            就延长key的过期时间.从而减小不必要的阻塞.

     */

    /*
        分布式事务


     */



}
